{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "e4cf65a6",
   "metadata": {},
   "source": [
    "# MindSpore Quantum 量子计算编程与实践：轻松上手量子卷积神经网络\n",
    "\n",
    "## 基础知识\n",
    "\n",
    "安装 MindQuantum 0.7.0 版本并导入"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "07cf94b6",
   "metadata": {},
   "outputs": [],
   "source": [
    "!pip install mindquantum==0.7.0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "f7d2b6a5",
   "metadata": {
    "scrolled": false
   },
   "outputs": [],
   "source": [
    "from mindquantum import *\n",
    "import numpy as np"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8400830e",
   "metadata": {},
   "source": [
    "### 量子态和模拟器\n",
    "\n",
    "在 MindQuantum 中，对量子系统的模拟主要由量子模拟器 `Simulator` 完成。`Simulator` 中维护着一个量子态，通过对其施加量子门、量子线路或者直接设置的方式，可以改变这个量子态，从而完成计算任务。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "id": "5d4c7391",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "projectq simulator with 1 qubit (little endian).\n",
      "Current quantum state:\n",
      "1¦0⟩\n"
     ]
    }
   ],
   "source": [
    "sim = Simulator('projectq', n_qubits=1) # 第一个参数为模拟器后端的名字，第二个参数为模拟器的比特数。\n",
    "print(sim)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "928f5cbe",
   "metadata": {},
   "source": [
    "模拟器中，所有比特的初态都是 $|0\\rangle$。我们可以通过 `get_qs(ket=False)` 来获取模拟器中的量子态，其中参数 `ket` 表示是否以狄拉克符号形式表示量子态，默认为 `False`，采用数组形式表示。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "id": "dbffab4d",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "量子态的数组形式为：\t [1.+0.j 0.+0.j]\n",
      "量子态的狄拉克形式为：\t 1¦0⟩\n"
     ]
    }
   ],
   "source": [
    "state_array = sim.get_qs()       # 采用默认的数组形式，显示量子态\n",
    "print('量子态的数组形式为：\\t', state_array)\n",
    "\n",
    "state_ket = sim.get_qs(ket=True) # 采用狄拉克符号形式，显示量子态\n",
    "print('量子态的狄拉克形式为：\\t', state_ket)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a042d65b",
   "metadata": {},
   "source": [
    "可以通过 `set_qs()` 函数直接对模拟器中的量子态进行赋值。比如，在下面代码中，我们就通过该方式将模拟器的量子态赋值为 $|1\\rangle$。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "id": "49861a4b",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "初始量子态为：\t 1¦0⟩\n",
      "最终量子态为：\t 1¦1⟩\n"
     ]
    }
   ],
   "source": [
    "sim = Simulator('projectq', n_qubits=1)\n",
    "state_temp = np.array([0., 1.])\n",
    "\n",
    "init_state = sim.get_qs(ket=True)\n",
    "\n",
    "sim.set_qs(state_temp)\n",
    "final_state = sim.get_qs(ket=True)\n",
    "\n",
    "print('初始量子态为：\\t', init_state)\n",
    "print('最终量子态为：\\t', final_state)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cd97e074",
   "metadata": {},
   "source": [
    "### 量子门\n",
    "\n",
    "量子门是量子算法的基本组成单元。通过施加一系列设计好的量子门，可以改变量子态，从而完成计算任务。 MindQuantum 预置了一系列常见的量子门，比如 `X`, `Y`, `Z`, `H`, `RX`, `RY`, `RZ` 等，灵活使用他们，可以完成任意逻辑操作。我们以 `X` 门为例，介绍一下如何使用它们。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "20902207",
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "X(0)"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X.on(0) # on() 表示量子门作用在哪个量子比特上。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "feb352b3",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0, 1],\n",
       "       [1, 0]])"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X.matrix() # matrix() 函数可以展示量子门的矩阵形式"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "ac215b88",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "X(1 <-: 0)"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X.on(1,0) # CNOT 门。 on() 中的参数可以为多个，此时，第一个为受控比特，第二个为控制比特。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "c9eff90c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "X(2 <-: 0 1)"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X.on(2,[0,1]) # Toffli 门。受控比特 和 控制比特 都可以有多个，同样性质的比特，用列表封装在一起。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "f09ac5d7",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "RX(π|0)"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "RX(np.pi).on(0) # 旋转门的旋转角度可以自己定义。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cd575ba4",
   "metadata": {},
   "source": [
    "除了上面旋转角度固定的量子门，还可以定义参数门：先设置参数名，其具体取值在后面根据需要进行设定。这种量子门对于量子变分算法和量子机器学习至关重要。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "b587e226",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "RX(theta|0)"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "RX('theta').on(0) # 此处为一个参数门，其参数名为 'theta'，其值可暂不赋予。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3d4cf25e",
   "metadata": {},
   "source": [
    "### 量子线路\n",
    "\n",
    "对量子门进行有序排列就可以得到量子线路。一段有意义的量子线路，就构成了量子算法。\n",
    "\n",
    "用 MindQuantum 搭建量子线路是非常简单的。目前支持一下几种搭建量子线路的方式：\n",
    "\n",
    "1. 采用 `+=` 形式，可读性强"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "ceb57c31",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "q0: ──X────RY(theta)──\n",
      "\n",
      "q1: ──Y───────────────\n"
     ]
    }
   ],
   "source": [
    "circ = Circuit()\n",
    "circ += X.on(0)\n",
    "circ += RY('theta').on(0)\n",
    "circ += Y.on(1)\n",
    "print(circ)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "363f1531",
   "metadata": {},
   "source": [
    "2. 列表形式，简洁"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "37738d6e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "q0: ──X────RY(theta)──\n",
      "\n",
      "q1: ──Y───────────────\n"
     ]
    }
   ],
   "source": [
    "circ = Circuit([X.on(0), RY('theta').on(0)])\n",
    "circ.append(Y.on(1))\n",
    "print(circ)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "276d8d92",
   "metadata": {},
   "source": [
    "3. 函数形式，书写便捷"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "cec2d157",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "q0: ──X────RY(theta)──\n",
      "\n",
      "q1: ──Y───────────────\n"
     ]
    }
   ],
   "source": [
    "circ = Circuit().x(0).ry('theta',0).y(1)\n",
    "print(circ)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e5d6bd22",
   "metadata": {},
   "source": [
    "量子线路的作用。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "ecdf509d",
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "定义的量子线路为：\n"
     ]
    },
    {
     "data": {
      "image/svg+xml": [
       "<div class=\"nb-html-output output_area\"><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"216.8\" height=\"140\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<rect x=\"0\" y=\"0\" width=\"216.8\" height=\"140\" fill=\"#ffffff\" />\n",
       "<text x=\"20.0\" y=\"40.0\" font-size=\"16px\" dominant-baseline=\"middle\" text-anchor=\"start\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#252b3a\" >\n",
       "q0:\n",
       " </text>\n",
       "<text x=\"20.0\" y=\"100.0\" font-size=\"16px\" dominant-baseline=\"middle\" text-anchor=\"start\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#252b3a\" >\n",
       "q1:\n",
       " </text>\n",
       "<line x1=\"48.8\" x2=\"196.8\" y1=\"40.0\" y2=\"40.0\" stroke=\"#adb0b8\" stroke-width=\"1\" />\n",
       "<line x1=\"48.8\" x2=\"196.8\" y1=\"100.0\" y2=\"100.0\" stroke=\"#adb0b8\" stroke-width=\"1\" />\n",
       "\n",
       "<rect x=\"72.8\" y=\"20.0\" width=\"40.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#5e7ce0\" fill-opacity=\"1\" />\n",
       "<text x=\"92.8\" y=\"40.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "H\n",
       " </text>\n",
       "\n",
       "<circle cx=\"152.8\" cy=\"40.0\" r=\"4\" fill=\"#16acff\" />\n",
       "<line x1=\"152.8\" x2=\"152.8\" y1=\"40.0\" y2=\"100.0\" stroke=\"#16acff\" stroke-width=\"3\" />\n",
       "<rect x=\"132.8\" y=\"80.0\" width=\"40\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#16acff\" fill-opacity=\"1\" />\n",
       "<line x1=\"138.8\" x2=\"166.8\" y1=\"100.0\" y2=\"100.0\" stroke=\"#ffffff\" stroke-width=\"4\" />\n",
       "<line x1=\"152.8\" x2=\"152.8\" y1=\"86.0\" y2=\"114.0\" stroke=\"#ffffff\" stroke-width=\"4\" />\n",
       "</svg></div>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "初始态 |00〉态经过量子线路作用后，变为：\n",
      " √2/2¦00⟩\n",
      "√2/2¦11⟩\n"
     ]
    }
   ],
   "source": [
    "from IPython.display import display_svg\n",
    "circ = Circuit()\n",
    "circ += H.on(0)\n",
    "circ += X.on(1,0)\n",
    "print('定义的量子线路为：')\n",
    "display_svg(circ.svg())\n",
    "\n",
    "print('初始态 |00〉态经过量子线路作用后，变为：\\n', circ.get_qs(ket=True))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b5262a7a",
   "metadata": {},
   "source": [
    "单量子比特任意逻辑操作：通过改变其参数 `alpha`, `beta`, `theta`, 如下 `U3` 线路可以实现任意单量子比特逻辑操作。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "c77188a8",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<div class=\"nb-html-output output_area\"><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"476.8\" height=\"80\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<rect x=\"0\" y=\"0\" width=\"476.8\" height=\"80\" fill=\"#ffffff\" />\n",
       "<text x=\"20.0\" y=\"40.0\" font-size=\"16px\" dominant-baseline=\"middle\" text-anchor=\"start\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#252b3a\" >\n",
       "q0:\n",
       " </text>\n",
       "<line x1=\"48.8\" x2=\"456.8\" y1=\"40.0\" y2=\"40.0\" stroke=\"#adb0b8\" stroke-width=\"1\" />\n",
       "\n",
       "<rect x=\"72.8\" y=\"20.0\" width=\"80.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" />\n",
       "<text x=\"112.8\" y=\"36.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "RZ\n",
       " </text>\n",
       "<text x=\"112.8\" y=\"52.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "alpha\n",
       " </text>\n",
       "\n",
       "\n",
       "<rect x=\"172.8\" y=\"20.0\" width=\"40.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" />\n",
       "<text x=\"192.8\" y=\"36.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "RX\n",
       " </text>\n",
       "<text x=\"192.8\" y=\"52.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "-π/2\n",
       " </text>\n",
       "\n",
       "\n",
       "<rect x=\"232.8\" y=\"20.0\" width=\"40.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" />\n",
       "<text x=\"252.8\" y=\"36.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "RZ\n",
       " </text>\n",
       "<text x=\"252.8\" y=\"52.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "beta\n",
       " </text>\n",
       "\n",
       "\n",
       "<rect x=\"292.8\" y=\"20.0\" width=\"40.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" />\n",
       "<text x=\"312.8\" y=\"36.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "RX\n",
       " </text>\n",
       "<text x=\"312.8\" y=\"52.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "π/2\n",
       " </text>\n",
       "\n",
       "\n",
       "<rect x=\"352.8\" y=\"20.0\" width=\"80.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" />\n",
       "<text x=\"392.8\" y=\"36.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "RZ\n",
       " </text>\n",
       "<text x=\"392.8\" y=\"52.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "theta\n",
       " </text>\n",
       "\n",
       "</svg></div>"
      ],
      "text/plain": [
       "<mindquantum.io.display.circuit_svg_drawer.SVGCircuit at 0x27daf7482c8>"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "circ = U3('alpha','beta','theta', 0) # 调用 U3 函数可直接搭建 U3 线路。前三个参数为线路的参数名，最后一个参数指明作用到哪个比特。\n",
    "circ.svg()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a807eaa5",
   "metadata": {},
   "source": [
    "双量子比特任意逻辑操作：通过改变其参数，如下双量子比特线路可以实现任意双比特逻辑操作。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "f4c54dca",
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<div class=\"nb-html-output output_area\"><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"1316.8\" height=\"140\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<rect x=\"0\" y=\"0\" width=\"1316.8\" height=\"140\" fill=\"#ffffff\" />\n",
       "<text x=\"20.0\" y=\"40.0\" font-size=\"16px\" dominant-baseline=\"middle\" text-anchor=\"start\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#252b3a\" >\n",
       "q0:\n",
       " </text>\n",
       "<text x=\"20.0\" y=\"100.0\" font-size=\"16px\" dominant-baseline=\"middle\" text-anchor=\"start\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#252b3a\" >\n",
       "q1:\n",
       " </text>\n",
       "<line x1=\"48.8\" x2=\"1296.8\" y1=\"40.0\" y2=\"40.0\" stroke=\"#adb0b8\" stroke-width=\"1\" />\n",
       "<line x1=\"48.8\" x2=\"1296.8\" y1=\"100.0\" y2=\"100.0\" stroke=\"#adb0b8\" stroke-width=\"1\" />\n",
       "\n",
       "<rect x=\"72.8\" y=\"20.0\" width=\"80.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" />\n",
       "<text x=\"112.8\" y=\"36.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "RZ\n",
       " </text>\n",
       "<text x=\"112.8\" y=\"52.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "alpha_0_0\n",
       " </text>\n",
       "\n",
       "\n",
       "<rect x=\"172.8\" y=\"20.0\" width=\"40.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" />\n",
       "<text x=\"192.8\" y=\"36.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "RX\n",
       " </text>\n",
       "<text x=\"192.8\" y=\"52.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "-π/2\n",
       " </text>\n",
       "\n",
       "\n",
       "<rect x=\"232.8\" y=\"20.0\" width=\"80.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" />\n",
       "<text x=\"272.8\" y=\"36.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "RZ\n",
       " </text>\n",
       "<text x=\"272.8\" y=\"52.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "beta_0_0\n",
       " </text>\n",
       "\n",
       "\n",
       "<rect x=\"332.8\" y=\"20.0\" width=\"40.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" />\n",
       "<text x=\"352.8\" y=\"36.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "RX\n",
       " </text>\n",
       "<text x=\"352.8\" y=\"52.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "π/2\n",
       " </text>\n",
       "\n",
       "\n",
       "<rect x=\"392.8\" y=\"20.0\" width=\"80.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" />\n",
       "<text x=\"432.8\" y=\"36.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "RZ\n",
       " </text>\n",
       "<text x=\"432.8\" y=\"52.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "theta_0_0\n",
       " </text>\n",
       "\n",
       "\n",
       "<rect x=\"72.8\" y=\"80.0\" width=\"80.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" />\n",
       "<text x=\"112.8\" y=\"96.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "RZ\n",
       " </text>\n",
       "<text x=\"112.8\" y=\"112.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "alpha_1_0\n",
       " </text>\n",
       "\n",
       "\n",
       "<rect x=\"172.8\" y=\"80.0\" width=\"40.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" />\n",
       "<text x=\"192.8\" y=\"96.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "RX\n",
       " </text>\n",
       "<text x=\"192.8\" y=\"112.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "-π/2\n",
       " </text>\n",
       "\n",
       "\n",
       "<rect x=\"232.8\" y=\"80.0\" width=\"80.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" />\n",
       "<text x=\"272.8\" y=\"96.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "RZ\n",
       " </text>\n",
       "<text x=\"272.8\" y=\"112.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "beta_1_0\n",
       " </text>\n",
       "\n",
       "\n",
       "<rect x=\"332.8\" y=\"80.0\" width=\"40.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" />\n",
       "<text x=\"352.8\" y=\"96.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "RX\n",
       " </text>\n",
       "<text x=\"352.8\" y=\"112.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "π/2\n",
       " </text>\n",
       "\n",
       "\n",
       "<rect x=\"392.8\" y=\"80.0\" width=\"80.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" />\n",
       "<text x=\"432.8\" y=\"96.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "RZ\n",
       " </text>\n",
       "<text x=\"432.8\" y=\"112.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "theta_1_0\n",
       " </text>\n",
       "\n",
       "<circle cx=\"512.8\" cy=\"40.0\" r=\"4\" fill=\"#16acff\" />\n",
       "<line x1=\"512.8\" x2=\"512.8\" y1=\"40.0\" y2=\"100.0\" stroke=\"#16acff\" stroke-width=\"3\" />\n",
       "<rect x=\"492.8\" y=\"80.0\" width=\"40\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#16acff\" fill-opacity=\"1\" />\n",
       "<line x1=\"498.8\" x2=\"526.8\" y1=\"100.0\" y2=\"100.0\" stroke=\"#ffffff\" stroke-width=\"4\" />\n",
       "<line x1=\"512.8\" x2=\"512.8\" y1=\"86.0\" y2=\"114.0\" stroke=\"#ffffff\" stroke-width=\"4\" />\n",
       "\n",
       "<rect x=\"552.8\" y=\"20.0\" width=\"80.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" />\n",
       "<text x=\"592.8\" y=\"36.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "RY\n",
       " </text>\n",
       "<text x=\"592.8\" y=\"52.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "phi_0_0\n",
       " </text>\n",
       "\n",
       "\n",
       "<rect x=\"552.8\" y=\"80.0\" width=\"80.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" />\n",
       "<text x=\"592.8\" y=\"96.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "RZ\n",
       " </text>\n",
       "<text x=\"592.8\" y=\"112.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "phi_1_0\n",
       " </text>\n",
       "\n",
       "<circle cx=\"672.8\" cy=\"100.0\" r=\"4\" fill=\"#16acff\" />\n",
       "<line x1=\"672.8\" x2=\"672.8\" y1=\"40.0\" y2=\"100.0\" stroke=\"#16acff\" stroke-width=\"3\" />\n",
       "<rect x=\"652.8\" y=\"20.0\" width=\"40\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#16acff\" fill-opacity=\"1\" />\n",
       "<line x1=\"658.8\" x2=\"686.8\" y1=\"40.0\" y2=\"40.0\" stroke=\"#ffffff\" stroke-width=\"4\" />\n",
       "<line x1=\"672.8\" x2=\"672.8\" y1=\"26.0\" y2=\"54.0\" stroke=\"#ffffff\" stroke-width=\"4\" />\n",
       "\n",
       "<rect x=\"712.8\" y=\"20.0\" width=\"80.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" />\n",
       "<text x=\"752.8\" y=\"36.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "RY\n",
       " </text>\n",
       "<text x=\"752.8\" y=\"52.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "phi_0_1\n",
       " </text>\n",
       "\n",
       "<circle cx=\"832.8\" cy=\"40.0\" r=\"4\" fill=\"#16acff\" />\n",
       "<line x1=\"832.8\" x2=\"832.8\" y1=\"40.0\" y2=\"100.0\" stroke=\"#16acff\" stroke-width=\"3\" />\n",
       "<rect x=\"812.8\" y=\"80.0\" width=\"40\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#16acff\" fill-opacity=\"1\" />\n",
       "<line x1=\"818.8\" x2=\"846.8\" y1=\"100.0\" y2=\"100.0\" stroke=\"#ffffff\" stroke-width=\"4\" />\n",
       "<line x1=\"832.8\" x2=\"832.8\" y1=\"86.0\" y2=\"114.0\" stroke=\"#ffffff\" stroke-width=\"4\" />\n",
       "\n",
       "<rect x=\"872.8\" y=\"20.0\" width=\"80.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" />\n",
       "<text x=\"912.8\" y=\"36.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "RZ\n",
       " </text>\n",
       "<text x=\"912.8\" y=\"52.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "alpha_0_1\n",
       " </text>\n",
       "\n",
       "\n",
       "<rect x=\"972.8\" y=\"20.0\" width=\"40.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" />\n",
       "<text x=\"992.8\" y=\"36.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "RX\n",
       " </text>\n",
       "<text x=\"992.8\" y=\"52.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "-π/2\n",
       " </text>\n",
       "\n",
       "\n",
       "<rect x=\"1032.8\" y=\"20.0\" width=\"80.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" />\n",
       "<text x=\"1072.8\" y=\"36.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "RZ\n",
       " </text>\n",
       "<text x=\"1072.8\" y=\"52.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "beta_0_2\n",
       " </text>\n",
       "\n",
       "\n",
       "<rect x=\"1132.8\" y=\"20.0\" width=\"40.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" />\n",
       "<text x=\"1152.8\" y=\"36.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "RX\n",
       " </text>\n",
       "<text x=\"1152.8\" y=\"52.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "π/2\n",
       " </text>\n",
       "\n",
       "\n",
       "<rect x=\"1192.8\" y=\"20.0\" width=\"80.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" />\n",
       "<text x=\"1232.8\" y=\"36.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "RZ\n",
       " </text>\n",
       "<text x=\"1232.8\" y=\"52.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "theta_0_3\n",
       " </text>\n",
       "\n",
       "\n",
       "<rect x=\"872.8\" y=\"80.0\" width=\"80.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" />\n",
       "<text x=\"912.8\" y=\"96.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "RZ\n",
       " </text>\n",
       "<text x=\"912.8\" y=\"112.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "alpha_1_1\n",
       " </text>\n",
       "\n",
       "\n",
       "<rect x=\"972.8\" y=\"80.0\" width=\"40.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" />\n",
       "<text x=\"992.8\" y=\"96.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "RX\n",
       " </text>\n",
       "<text x=\"992.8\" y=\"112.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "-π/2\n",
       " </text>\n",
       "\n",
       "\n",
       "<rect x=\"1032.8\" y=\"80.0\" width=\"80.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" />\n",
       "<text x=\"1072.8\" y=\"96.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "RZ\n",
       " </text>\n",
       "<text x=\"1072.8\" y=\"112.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "beta_1_1\n",
       " </text>\n",
       "\n",
       "\n",
       "<rect x=\"1132.8\" y=\"80.0\" width=\"40.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" />\n",
       "<text x=\"1152.8\" y=\"96.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "RX\n",
       " </text>\n",
       "<text x=\"1152.8\" y=\"112.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "π/2\n",
       " </text>\n",
       "\n",
       "\n",
       "<rect x=\"1192.8\" y=\"80.0\" width=\"80.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" />\n",
       "<text x=\"1232.8\" y=\"96.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "RZ\n",
       " </text>\n",
       "<text x=\"1232.8\" y=\"112.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "theta_1_1\n",
       " </text>\n",
       "\n",
       "</svg></div>"
      ],
      "text/plain": [
       "<mindquantum.io.display.circuit_svg_drawer.SVGCircuit at 0x27daf751808>"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "circ = Circuit()\n",
    "circ += U3('alpha_0_0','beta_0_0','theta_0_0', 0)\n",
    "circ += U3('alpha_1_0','beta_1_0','theta_1_0', 1)\n",
    "circ += X.on(1,0)\n",
    "circ += RY('phi_0_0').on(0)\n",
    "circ += RZ('phi_1_0').on(1)\n",
    "circ += X.on(0,1)\n",
    "circ += RY('phi_0_1').on(0)\n",
    "circ += X.on(1,0)\n",
    "circ += U3('alpha_0_1','beta_0_2','theta_0_3', 0)\n",
    "circ += U3('alpha_1_1','beta_1_1','theta_1_1', 1) \n",
    "\n",
    "circ.svg()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fd65283e",
   "metadata": {},
   "source": [
    "# 实战作业：\n",
    "\n",
    "基于 MindQuantum 设计量子线路，制备出如图布洛赫球面赤道上的四个量子态（红色字体），\n",
    "可忽略整体相位。实现后请以 PR 形式提交到 Gitee MindQuantum 的 research 分支。在线路搭建完成后，如果输入结果 `是否符合预期目标？ True` 则表示成功。\n",
    "\n",
    "<img src='./practice.png' width='40%'>\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "195dc362",
   "metadata": {},
   "source": [
    "1. 制备 $(|00\\rangle+|11\\rangle)/\\sqrt(2)$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "cf03fc8b",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "欲制备的量子态为：\n",
      " [0.70710678 0.70710678]\n",
      "\n",
      "您制备的量子态为：\n",
      " [0.70710678+0.j 0.70710678+0.j]\n",
      "\n",
      "是否符合预期目标？ True\n"
     ]
    }
   ],
   "source": [
    "target_state = np.array([1, 1]/np.sqrt(2))\n",
    "print('欲制备的量子态为：\\n', target_state)\n",
    "target_state = np.mat(target_state.reshape((2,1)))\n",
    "\n",
    "# 请搭建量子线路\n",
    "circ = Circuit()\n",
    "circ += H.on(0)\n",
    "\n",
    "state = circ.get_qs()\n",
    "print('\\n您制备的量子态为：\\n', state)\n",
    "\n",
    "state = np.mat(state).reshape((2,1))\n",
    "print('\\n是否符合预期目标？', np.allclose((np.abs(target_state.H@state)**2)[0,0].real, 1))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9b7d6a60",
   "metadata": {},
   "source": [
    "2. 制备 $(|00\\rangle+i|11\\rangle)/\\sqrt(2)$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "id": "ebfaec5d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "欲制备的量子态为：\n",
      " [0.70710678+0.j         0.        +0.70710678j]\n",
      "\n",
      "您制备的量子态为：\n",
      " [4.32963729e-17-0.70710678j 4.32963729e-17+0.70710678j]\n",
      "\n",
      "是否符合预期目标？ False\n"
     ]
    }
   ],
   "source": [
    "target_state = np.array([1, 1j]/np.sqrt(2))\n",
    "print('欲制备的量子态为：\\n', target_state)\n",
    "target_state = np.mat(target_state.reshape((2,1)))\n",
    "\n",
    "# 请搭建量子线路\n",
    "circ = Circuit()\n",
    "circ += H.on(0)\n",
    "circ += RZ(np.pi/2).on(0)\n",
    "\n",
    "state = circ.get_qs()\n",
    "print('\\n您制备的量子态为：\\n', state)\n",
    "\n",
    "state = np.mat(state).reshape((2,1))\n",
    "print('\\n是否符合预期目标？', np.allclose((np.abs(target_state.H@state)**2)[0,0].real, 1))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "75c6312a",
   "metadata": {},
   "source": [
    "3. 制备 $(|00\\rangle-|11\\rangle)/\\sqrt(2)$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "293f507d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "欲制备的量子态为：\n",
      " [ 0.70710678 -0.70710678]\n",
      "\n",
      "您制备的量子态为：\n",
      " [0.70710678+0.j 0.70710678+0.j]\n",
      "\n",
      "是否符合预期目标？ False\n"
     ]
    }
   ],
   "source": [
    "target_state = np.array([1, -1]/np.sqrt(2))\n",
    "print('欲制备的量子态为：\\n', target_state)\n",
    "target_state = np.mat(target_state.reshape((2,1)))\n",
    "\n",
    "# 请搭建量子线路\n",
    "circ = Circuit()\n",
    "circ += H.on(0)\n",
    "circ += RZ(np.pi).on(0)\n",
    "\n",
    "state = circ.get_qs()\n",
    "print('\\n您制备的量子态为：\\n', state)\n",
    "\n",
    "state = np.mat(state).reshape((2,1))\n",
    "print('\\n是否符合预期目标？', np.allclose((np.abs(target_state.H@state)**2)[0,0].real, 1))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d8a3b503",
   "metadata": {},
   "source": [
    "4. 制备 $(|00\\rangle-i|11\\rangle)/\\sqrt(2)$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "2b0a9c01",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "欲制备的量子态为：\n",
      " [ 0.70710678+0.j         -0.        -0.70710678j]\n",
      "\n",
      "您制备的量子态为：\n",
      " [0.70710678+0.j 0.70710678+0.j]\n",
      "\n",
      "是否符合预期目标？ False\n"
     ]
    }
   ],
   "source": [
    "target_state = np.array([1, -1j]/np.sqrt(2))\n",
    "print('欲制备的量子态为：\\n', target_state)\n",
    "target_state = np.mat(target_state.reshape((2,1)))\n",
    "\n",
    "# 请搭建量子线路\n",
    "circ = Circuit()\n",
    "circ += H.on(0)\n",
    "\n",
    "state = circ.get_qs()\n",
    "print('\\n您制备的量子态为：\\n', state)\n",
    "\n",
    "state = np.mat(state).reshape((2,1))\n",
    "print('\\n是否符合预期目标？', np.allclose((np.abs(target_state.H@state)**2)[0,0].real, 1))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bb1637d7",
   "metadata": {},
   "source": [
    "### 量子测量 和 期望值：\n",
    "\n",
    "量子计算的结果要通过对量子比特进行特定的测量来提取。得到不同测量结果的概率由量子比特的量子态决定。\n",
    "\n",
    "实际任务中，往往需要根据测量结果，对量子线路的参数甚至结构进行调节。\n",
    "\n",
    "在 MindQuantum 中，只要在量子线路添加测量门就可以实现测量操作：`measure(key, obj_qubit=None)`，其参数 `obj_qubit` 表示作用到哪个量子比特上， `key` 表示测量门的名字，如果 `obj_qubit=None`，则 `key` 应为整数，来表示作用到哪个量子比特上。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "id": "ebeaabb4",
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "测量前的量子态为： 1¦1⟩\n",
      "\n",
      "搭建的量子线路为：\n"
     ]
    },
    {
     "data": {
      "image/svg+xml": [
       "<div class=\"nb-html-output output_area\"><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"216.8\" height=\"80\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<rect x=\"0\" y=\"0\" width=\"216.8\" height=\"80\" fill=\"#ffffff\" />\n",
       "<text x=\"20.0\" y=\"40.0\" font-size=\"16px\" dominant-baseline=\"middle\" text-anchor=\"start\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#252b3a\" >\n",
       "q0:\n",
       " </text>\n",
       "<line x1=\"48.8\" x2=\"196.8\" y1=\"40.0\" y2=\"40.0\" stroke=\"#adb0b8\" stroke-width=\"1\" />\n",
       "\n",
       "<rect x=\"72.8\" y=\"20.0\" width=\"40.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#5e7ce0\" fill-opacity=\"1\" />\n",
       "<text x=\"92.8\" y=\"40.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "X\n",
       " </text>\n",
       "\n",
       "<rect x=\"132.8\" y=\"20.0\" width=\"40\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#ff7272\" fill-opacity=\"1\" />\n",
       "<circle cx=\"152.8\" cy=\"50.4\" r=\"1.6\" fill=\"#ffffff\" />\n",
       "<path d=\"M 140.0 50.4 A 12.8 12.8 0 0 1 165.60000000000002 50.4\" stroke=\"#ffffff\" stroke-width=\"2.4000000000000004\" fill-opacity=\"0\" />\n",
       "<path d=\"M 156.90184831748593 33.93539030917347 L 165.21569219381652 29.135390309173467 L 165.21569219381652 38.73539030917347 L 161.8901546432843 36.815390309173466 L 154.04707658144957 50.4 L 152.38430780618347 49.44 L 160.22738586801816 35.85539030917347 Z\" fill=\"#ffffff\" />\n",
       "</svg></div>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "测量后的量子态为： 1¦1⟩\n"
     ]
    }
   ],
   "source": [
    "circ = Circuit()\n",
    "circ += X.on(0)\n",
    "\n",
    "print('测量前的量子态为：', circ.get_qs(ket=True))\n",
    "circ.measure(0)\n",
    "\n",
    "print('\\n搭建的量子线路为：')\n",
    "display_svg(circ.svg())\n",
    "\n",
    "print('测量后的量子态为：', circ.get_qs(ket=True) )"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e2801f60",
   "metadata": {},
   "source": [
    "可见，初态 $|0\\rangle$ 经 `X` 门作用后变为 $|1\\rangle$。测量后，量子态坍缩到了基矢态 $|1\\rangle$ 上。\n",
    "请尝试多次运行这段代码，会发现测量结果一直不变。这是因为，根据量子力学，对于一个量子态 $|\\psi\\rangle = \\alpha|0\\rangle+\\beta|1\\rangle$,\n",
    "测量得到基矢态 $|0\\rangle$ 和 $|1\\rangle$ 的概率分别为 $|\\alpha|^2$ 和 $|\\beta|^2$。\n",
    "所以，在 `X` 门将 $|0\\rangle$ 态转变为 $|1\\rangle$ 后， $|\\psi\\rangle=|1\\rangle$，测量得到 $|1\\rangle$ 的概率为 1。 \n",
    "\n",
    "让我们尝试一下另一个门 `H` 门，这个门会将 $|0\\rangle$ 态转变为 $(|0\\rangle+|1\\rangle)/\\sqrt(2)$。多次运行下面代码，会发现测量后，会随机坍缩到基矢 $|0\\rangle$ 态和基矢 $|1\\rangle$ 态上，且频次基本相同。这是因为量子力学预测，坍缩到两个基矢态的概率都为 $|\\frac{1}{\\sqrt{2}}|^2=1/2$。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "id": "ed0bf324",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "初始量子态为：\n",
      " 1¦0⟩\n",
      "\n",
      "测量前的量子态为：\n",
      " √2/2¦0⟩\n",
      "√2/2¦1⟩\n",
      "\n",
      "搭建的量子线路为：\n"
     ]
    },
    {
     "data": {
      "image/svg+xml": [
       "<div class=\"nb-html-output output_area\"><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"216.8\" height=\"80\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<rect x=\"0\" y=\"0\" width=\"216.8\" height=\"80\" fill=\"#ffffff\" />\n",
       "<text x=\"20.0\" y=\"40.0\" font-size=\"16px\" dominant-baseline=\"middle\" text-anchor=\"start\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#252b3a\" >\n",
       "q0:\n",
       " </text>\n",
       "<line x1=\"48.8\" x2=\"196.8\" y1=\"40.0\" y2=\"40.0\" stroke=\"#adb0b8\" stroke-width=\"1\" />\n",
       "\n",
       "<rect x=\"72.8\" y=\"20.0\" width=\"40.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#5e7ce0\" fill-opacity=\"1\" />\n",
       "<text x=\"92.8\" y=\"40.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "H\n",
       " </text>\n",
       "\n",
       "<rect x=\"132.8\" y=\"20.0\" width=\"40\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#ff7272\" fill-opacity=\"1\" />\n",
       "<circle cx=\"152.8\" cy=\"50.4\" r=\"1.6\" fill=\"#ffffff\" />\n",
       "<path d=\"M 140.0 50.4 A 12.8 12.8 0 0 1 165.60000000000002 50.4\" stroke=\"#ffffff\" stroke-width=\"2.4000000000000004\" fill-opacity=\"0\" />\n",
       "<path d=\"M 156.90184831748593 33.93539030917347 L 165.21569219381652 29.135390309173467 L 165.21569219381652 38.73539030917347 L 161.8901546432843 36.815390309173466 L 154.04707658144957 50.4 L 152.38430780618347 49.44 L 160.22738586801816 35.85539030917347 Z\" fill=\"#ffffff\" />\n",
       "</svg></div>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "测量后的量子态为：\n",
      " 1¦0⟩\n"
     ]
    }
   ],
   "source": [
    "circ = Circuit()\n",
    "print('初始量子态为：\\n', circ.get_qs(ket=True))\n",
    "\n",
    "circ += H.on(0)\n",
    "\n",
    "print('\\n测量前的量子态为：\\n', circ.get_qs(ket=True))\n",
    "\n",
    "circ.measure(0)\n",
    "print('\\n搭建的量子线路为：')\n",
    "display_svg(circ.svg())\n",
    "\n",
    "print('测量后的量子态为：\\n', circ.get_qs(ket=True))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f73d4b35",
   "metadata": {},
   "source": [
    "下面我们尝试做一个更有意思的实验：量子线路由一个 RX($\\theta$) 门构成，其参数 $\\theta$ 从 0 变化到 $2\\pi$, 观察其测量结果为 $|0\\rangle$ 和 $|1\\rangle$ 的概率变化。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "35024162",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "image/png": "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pCAuLg6pqanYtGlTg8f/5z//wbhx49CmTRvExsaiY8eOePfddyNUWnIK2+tVJtUgsj35FNsXVB9bg5u8vDxkZmYiOzsbW7ZsQefOnZGeno6DBw/WeXwwGMStt96KPXv2ID8/Hzt37sSCBQvQrl27CJecnMDWepVJNYhsTT7F9gU1JErTNM2uJ09NTcW1116LF154AQAQCoWQnJyMBx54AJMnTz7n+JdeeglPP/00duzYgSY6v9UqKytRWVlZ83NFRQWSk5NRXl6O+Ph4c/4Qss0TTwBPPqnv2KZNgaNHTargBg0Cli/Xd2x2tigokRepqri49Hah/POfQK9eYT9tYSHQu7e+YwMB4MQJBjduV1FRgYSEBF3f37b13ASDQWzevBm9z/h0RkdHo3fv3iguLq7znIKCAqSlpWHcuHFISkrClVdeiRkzZkBtoCWQm5uLhISEmltycrLpfwvZx5akfqoKrF6t71gm1SCvsyn5FJP2UUMMBTcff/xx2E98+PBhqKqKpKSkWvcnJSWhtLS0znO+++475OfnQ1VVvPvuu8jKysIzzzyD6dOn1/s8U6ZMQXl5ec1t3759YZednEO2Xv3oIxOetKhIjHPpwaQa5Acyyafeey/soSlVBf7xD33Hsn3hT4aCm1/96le4+OKLMX369IgGC6FQCK1atcJf//pXdO3aFRkZGfjjH/+Il156qd5zYmNjER8fX+tG3iJTr65fb8ITNvB5OweTapAfyCSfOnECWLcurKdbt07/lDe2L/zJUHDz/fffY/z48cjPz8dFF12E9PR0LF26FEG9rVkAiYmJUBQFZWVlte4vKytD69at6zynTZs26NixI5QzPqmXX345SktLpZ6bvEWmXt24McxGo0yedybVID+RCeT//vewnmrFCv3Hsn3hT4aCm8TEREycOBElJSX45JNP0LFjR9x///1o27YtHnzwQWzdurXRxwgEAujatSsKCwtr7guFQigsLERaWlqd59x444345ptvEAqFau7btWsX2rRpg0AgYORPIY/QW4GFvWpKZu0pk2qQn/TsCTRrpu/Y+fMNtzJUVZyuR7NmbF/4lmaC77//XsvOztZiY2O18847T1MURbvpppu0L7/8ssHzlixZosXGxmqvvvqqtm3bNu3ee+/VWrRooZWWlmqapmkjR47UJk+eXHP83r17tebNm2vjx4/X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FRWlffDBB41ek5rG69LJUM8qt1deeUXbtWuXBkD73//935rjb7/9dq1Fixba+vXrrS+b5c9A5BCNXWx/+9vftBtvvLHWOQ1dvGSvTz75RIuJidEuu+wybcOGDdq2bdu0wYMHax06dNCOHDmirV27VouJibF8ySk17Le//a32s5/9TAsEAtp///d/a7169dI++OADTdMavyY1TeN1SYZwQjH5RnUSsTO9++67Nf//85//fM5qjLOPJ+coKSnBZZddhkcffRSDBg1CeXk50tPTsWbNGrRo0QJbt27FZZddZvmSU2rYwoUL6/1dY9ckUPcqKV6X1BhmKCb60cyZMzF8+HAkJyfbXRTSYdy4cThy5AgWL15sd1HIQrwuyQgGN0TkSjfeeCP69evHLU6I6BxcLUVErqNpGr744gvmsCGiOrHnhoiIiDyFPTdERETkKQxuiIiIyFMY3BAREZGnMLghIiIiT2FwQ0RERJ7C4IaIiIg8hcENEREReQqDGyIiIvIUBjdE5AmapmH27Nno0KEDmjVrhjvuuAPl5eV2F4uIbMDghog84ZFHHsH8+fOxaNEirFu3Dps3b8YTTzxhd7GIyAbcfoGIXO+TTz5BWloaPv30U1xzzTUAgGnTpuHNN9/Ezp07bS4dEUUae26IyPVmzZqFXr161QQ2AJCUlITDhw/bWCoisguDGyJytcrKSrzzzju48847a91/6tQpJCQk2FQqIrITh6WIyNWKi4txww03IC4uDoqi1Nx/+vRp3HLLLXjvvfdsLB0R2SHG7gIQEYVj165dOO+881BSUlLr/l//+te48cYb7SkUEdmKwQ0RuVpFRQUSExNxySWX1Nz3v//7v/j6668xaNAgG0tGRHbhnBsicrXExESUl5fjzBH2p556Cn369EGnTp1sLBkR2YU9N0Tkar/85S9x6tQp/OlPf8KwYcPw5ptvYtWqVdi0aZPdRSMim7DnhohcLSkpCa+++irmz5+PK664Ahs3bsT69euRnJxsd9GIyCZcLUVERESewp4bIiIi8hQGN0REROQpDG6IiIjIUxjcEBERkacwuCEiIiJPYXBDREREnsLghoiIiDyFwQ0RERF5CoMbIiIi8hQGN0REROQpDG6IiIjIU/4//CdITqmzW4cAAAAASUVORK5CYII=\n",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "\n",
    "length = 1000\n",
    "prob_0 = []\n",
    "prob_1 = []\n",
    "\n",
    "for i in range(length+1):\n",
    "    theta = i*2*np.pi/length\n",
    "    circ = Circuit(RX(theta).on(0))\n",
    "    \n",
    "    state_array = circ.get_qs()\n",
    "    prob_0.append(np.abs(state_array[0])**2)\n",
    "    prob_1.append(np.abs(state_array[1])**2)\n",
    "\n",
    "## 可视化\n",
    "plt.figure()\n",
    "plt.plot(prob_0, label = r'$|0\\rangle$', linestyle='--', marker='o', color='b')\n",
    "plt.plot(prob_1, label = r'$|1\\rangle$', linestyle='--', marker='o', color='r')\n",
    "plt.legend() \n",
    "plt.xlabel(r'$\\theta$', fontsize=10)\n",
    "plt.xticks(ticks=[0, 251, 501, 751, 1001], labels=['0', r'$\\pi/2$', r'$pi$', r'$3\\pi/2$', r'$2\\pi$'])\n",
    "plt.ylabel('Probability', fontsize=10)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1409ad5b",
   "metadata": {},
   "source": [
    "对于单个量子比特， $|0\\rangle$ 态，对应的能量为 1，而 $|1\\rangle$ 态对应的能量为 -1。对某一量子态 $$|\\psi\\rangle=\\alpha|0\\rangle+\\beta|1\\rangle,$$ 其能量期望值为 $$|\\alpha|^2*(1)+|\\beta|^2*(-1)=|\\alpha|^2-|\\beta|^2.$$\n",
    "\n",
    "在 MindQuantum 中，这可以直接通过调用函数 `sim.get_expectation()` 来直接获得。如下：\n",
    "\n",
    "下面我们绘出随着 RX($\\theta$) 中参数 $\\theta$ 的变化，能量期望值的变化情况："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "fc39fb15",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "\n",
    "length = 1000\n",
    "delta_theta = 2*np.pi/length\n",
    "expectation = []\n",
    "sim = Simulator('projectq', 1)\n",
    "\n",
    "for i in range(length+1):\n",
    "    sim.apply_circuit(Circuit(RX(delta_theta).on(0)))\n",
    "    expectation.append(sim.get_expectation(Hamiltonian(QubitOperator('Z0'))).real)\n",
    "    \n",
    "plt.figure()\n",
    "plt.plot(expectation, label = 'expectation', linestyle='--', marker='o', color='b')\n",
    "plt.legend() \n",
    "plt.xlabel(r'$\\theta$', fontsize=10)\n",
    "plt.xticks(ticks=[0, 251, 501, 751, 1001], labels=['0', r'$\\pi/2$', r'$pi$', r'$3\\pi/2$', r'$2\\pi$'])\n",
    "plt.ylabel('Expectation ', fontsize=10)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1ef9d07f",
   "metadata": {},
   "source": [
    "## 量子变分线路 和 量子神经网络\n",
    "\n",
    "量子变分线路是指构建的量子线路含有参数量子门，其参数取值可在建立线路后，根据需要进行调节。这和经典的神经网络很像：先定义一个变量名，之后再根据反向传播算法对其参数进行更新。所以，这种量子变分线路，有时也被形象地称为 “量子神经网络”。\n",
    "\n",
    "下面的代码就定义了一段量子变分线路 —— 在搭建好线路后，再对线路的参数进行赋值，从而得到演化后的量子态。这部分量子线路也经常被称为拟设线路 `ansatz`。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "id": "cc78c9de",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "对变分线路参数进行赋值后，其前向传播所得的量子态为：\n",
      "(0.09933466539753061-0.19767681165408385j)¦0⟩\n",
      "(0.9751703272018158-0.009966711079379187j)¦1⟩\n"
     ]
    }
   ],
   "source": [
    "ansatz = Circuit()\n",
    "ansatz += RX('alpha').on(0)\n",
    "ansatz += RY('beta').on(0)\n",
    "ansatz += X.on(0)\n",
    "ansatz += RX('theta').on(0)\n",
    "\n",
    "alpha = 0.1\n",
    "beta = 0.2\n",
    "theta = 0.3\n",
    "\n",
    "print('对变分线路参数进行赋值后，其前向传播所得的量子态为：')\n",
    "print(ansatz.get_qs(pr={'alpha':alpha, 'beta':beta, 'theta':theta}, ket=True))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "332d6899",
   "metadata": {},
   "source": [
    "`ansatz` 不仅可以进行前向传递，还可以进行反向传播：通过如 “中心差分” 等求导方法，求得各参数相对于目标函数（一般而言是某一力学量在量子态下的期望值）的梯度，然后用诸如 `Adam` 等优化器就可以对参数进行更新。\n",
    "\n",
    "在 MindQuantum 中，对期望值和导数的计算由模拟器完成，我们可通过函数 `sim.get_expectation_with_grad()` 进行获得。而由于量子计算框架 MindQuantum 和 经典机器学习框架 MindSpore 深度融合，参数更新部分则可以直接采用 MindSpore 来完成。\n",
    "\n",
    "下面我们以一个简单的例子来演示, MindQuantum 如何对 `ansatz` 进行训练完成算法任务。\n",
    "\n",
    "此处，`ansatz` 仅包含一个 `RX` 门。任务目标是找到一个合适的旋转角度 $\\theta$ 来使得损失值（此处设为能量的期望值）最小。通过简单的推测，我们就知道该最小损失值为 -1（对应的量子态为 $|1\\rangle$），而对应的旋转角度应该是 $\\pm k\\pi$，其中 $k$ 为奇数。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "1f91671b",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "期望值随训练次数的变化：\n",
      "step is 10 \t  期望值：0.6510794\n",
      "step is 20 \t  期望值：-0.35128716\n",
      "step is 30 \t  期望值：-0.9855994\n",
      "step is 40 \t  期望值：-0.9401322\n",
      "step is 50 \t  期望值：-0.977039\n",
      "step is 60 \t  期望值：-0.998729\n",
      "step is 70 \t  期望值：-0.9956714\n",
      "step is 80 \t  期望值：-0.99999905\n",
      "step is 90 \t  期望值：-0.9994411\n",
      "step is 100 \t  期望值：-0.9999941\n",
      "\n",
      "训练后得到的最终旋转角度为： 3.141906\n"
     ]
    }
   ],
   "source": [
    "import mindspore as ms  # 导入 MindSpore，用来完成参数更新。\n",
    "ms.set_context(mode=ms.PYNATIVE_MODE, device_target=\"CPU\") # 模式需设为 PYNATIVE_MODE\n",
    "\n",
    "ansatz = Circuit()\n",
    "ansatz += RX('theta').on(0)\n",
    "ansatz.as_ansatz()  # 通过调用 as_ansatz() 函数来声明这部分量子线路的参数为可训练参数\n",
    "\n",
    "ham = Hamiltonian(QubitOperator('Z0')) # 目标函数，'Z0' 表示作用在第 0 个比特上的泡利 Z 矩阵。封装成为算符和哈密顿量。\n",
    "\n",
    "sim = Simulator('projectq', ansatz.n_qubits) # circ.n_qubits 可获取量子线路所用的比特数\n",
    "\n",
    "grad_ops = sim.get_expectation_with_grad(ham, ansatz) # 获取目标函数值 及 各参数相对目标函数的梯度\n",
    "\n",
    "qnet = MQAnsatzOnlyLayer(grad_ops) # 以层的形式对量子网络进行封装，且该层所有参数都为可训练参数。\n",
    "opti = ms.nn.Adam(qnet.trainable_params(), learning_rate=0.1)     # 需要优化的是量子网络中可训练的参数，学习率设为 0.1\n",
    "train = ms.nn.TrainOneStepCell(qnet, opti) # 每调用一次，就可以对网络的可训练参数进行一次更新\n",
    "\n",
    "print('期望值随训练次数的变化：')\n",
    "for i in range(1, 101): # 训练 100 次\n",
    "    res = train()\n",
    "    if i % 10 == 0: # 每 10 次训练，显示一次目标函数值\n",
    "        print(f'step is {i} \\t  期望值：{res[0]}')\n",
    "\n",
    "print('\\n训练后得到的最终旋转角度为：', qnet.weight.asnumpy()[0])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "22f1b39c",
   "metadata": {},
   "source": [
    "可见，经过 100 次训练，得到的旋转角度已经符合预期 $\\theta=\\pm k\\pi$。\n",
    "\n",
    "上面的例子中，量子线路只含有一个可变参数量子门的 `ansatz`。但有时，我们需要一个量子网络来对未知数据进行处理，也就是需要支持数据输入，这个不被训练的参数线路称为编码器 `encoder`。`encoder` 将经典信息编码为量子态，从而作为量子神经网络的输入，功能类似于经典神经网络中的输入层。\n",
    "\n",
    "在 MindQuantum 中，通过接口 `as_encoder` 来对某一段参数线路进行编码器声明。\n",
    "\n",
    "下面我们以一个简单的例子来进行示范：`encoder` 和 `ansatz` 都为一段只包含一个 `RX` 门的量子线路。后面我们将 `encoder` 的参数设置为 $\\pi/2$， 之后通过对 `ansatz` 的训练来寻找一个合适的旋转角度，使得能量期望值最小。从前面的讨论易知，该旋转角度为 $\\pi/2\\pm k\\pi$，其中 $k$ 为奇数。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "id": "0462d909",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "期望值随训练次数的变化：\n",
      "step is 10 \t  期望值：-0.76672345\n",
      "step is 20 \t  期望值：-0.9951272\n",
      "step is 30 \t  期望值：-0.95892125\n",
      "step is 40 \t  期望值：-0.99864537\n",
      "step is 50 \t  期望值：-0.99544454\n",
      "step is 60 \t  期望值：-0.99954396\n",
      "step is 70 \t  期望值：-0.9994277\n",
      "step is 80 \t  期望值：-0.99995875\n",
      "step is 90 \t  期望值：-0.9999125\n",
      "step is 100 \t  期望值：-0.99999976\n",
      "\n",
      "训练后得到的最终旋转角度为： 1.5715348\n"
     ]
    }
   ],
   "source": [
    "import mindspore as ms  \n",
    "ms.set_context(mode=ms.PYNATIVE_MODE, device_target=\"CPU\")\n",
    "\n",
    "encoder = Circuit()\n",
    "encoder += RX('alpha').on(0)\n",
    "encoder.as_encoder() # 通过调用 as_encoder 函数来声明某一段线路为编码器 encoder，这部分线路的参数为不可训练参数\n",
    "\n",
    "ansatz = Circuit()\n",
    "ansatz += RX('beta').on(0)\n",
    "ansatz.as_ansatz() # 通过调用 as_ansatz() 函数来声明这部分量子线路的参数为可训练参数\n",
    "\n",
    "circ = encoder + ansatz\n",
    "ham = Hamiltonian(QubitOperator('Z0'))\n",
    "sim = Simulator('projectq', circ.n_qubits)\n",
    "\n",
    "grad_ops = sim.get_expectation_with_grad(ham, circ)\n",
    "qnet = MQLayer(grad_ops) # 以层的形式对量子网络进行封装，该层既包含可训练参数，又包含不可训练参数\n",
    "\n",
    "opti = ms.nn.Adam(qnet.trainable_params(), learning_rate=0.1)     # 需要优化的是量子网络中可训练的参数，学习率设为 0.1\n",
    "train = ms.nn.TrainOneStepCell(qnet, opti)\n",
    "\n",
    "\n",
    "print('期望值随训练次数的变化：')\n",
    "for i in range(1, 101): # 训练 100 次\n",
    "    res = train(ms.Tensor([[np.pi/2]]))[0]\n",
    "    if i % 10 == 0: # 每 10 次训练，显示一次目标函数值\n",
    "        print(f'step is {i} \\t  期望值：{res[0]}')\n",
    "\n",
    "print('\\n训练后得到的最终旋转角度为：', qnet.weight.asnumpy()[0])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "04c698f5",
   "metadata": {},
   "source": [
    "可见，经过 100 次训练，得到的旋转角度已经符合预期 $\\theta=\\pi/2\\pm k\\pi$.\n",
    "\n",
    "# 量子卷积神经网络：\n",
    "\n",
    "量子卷积神经网络通过对量子比特施加卷积操作，将量子比特纠缠起来，提取信息。相比经典卷积神经网络，量子卷积神经网络可提取全局信息，而不仅仅是局部信息。下图为我们采用的量子卷积神经网络的整体结构图 [1]。\n",
    "\n",
    "<img src='./qcnn.png' width='80%'>\n",
    "\n",
    "其中，编码器 `encoder` 部分采用了密集比特编码。通过施加 `RX` 和 `RY` 门，每个量子比特可以编码 2 个像素信息。而卷积核则采用了可以实现任意双量子比特操的量子线路。通过多个卷积层操作，有效将所有比特纠缠起来。量子卷积网络可以有效提取图像特征，并通过丢比特的形式进行池化操作和引入非线性。最后通过比较第 3 和 第 7 个比特能量期望值大小，来作为分类依据。比如，若第 3 个比特期望值大于第 7 个比特的期望值，则规定该预测分类为 `0`，否则为 `1`。分类结果进过 Softmax 运算，与标签做交叉熵，作为损失函数。各参数相对损失函数的梯度由量子模拟器计算，并采用经典优化器 Adam 进行更新。\n",
    "\n",
    "下面是详细代码。\n",
    "\n",
    "导入所需库"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "id": "27a6e1c8",
   "metadata": {},
   "outputs": [],
   "source": [
    "from mindquantum import *\n",
    "import numpy as np\n",
    "import mindspore as ms\n",
    "from mindspore import nn, Tensor\n",
    "from mindspore.nn import Adam, TrainOneStepCell, LossBase\n",
    "import matplotlib.pyplot as plt\n",
    "ms.context.set_context(mode=ms.context.PYNATIVE_MODE, device_target=\"CPU\")\n",
    "ms.set_seed(2)\n",
    "np.random.seed(2)\n",
    "import random\n",
    "import copy "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ff4327cc",
   "metadata": {},
   "source": [
    "导入并处理图像数据。原始图像数据为 MNIST 手写字体，图像大小为 $28*28$，为便于模拟，我们将其压缩为 $4*4$ 的大小，并进行二值化和去冲突处理。所得保存在同目录下 `train.npy` 和 `eval.npy` 中，样本量分别为 4000 和 846。我们对其形式进行修整，从而可以作为量子编码器的输入。并从 `eval.npy` 中取 100 个样本作为本任务的验证集。 \n",
    "\n",
    "**注：** 由于 CSDN 页面无法上传数据集，读者如有需要，可以从我的 Gitee 仓库下载。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "id": "9ff53fe3",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(4000, 16)\n",
      "(4000,)\n",
      "(100, 16)\n",
      "(100,)\n"
     ]
    }
   ],
   "source": [
    "# 导入图像数据作为 训练集 和 验证集。x 是图像数据 y 为标签。\n",
    "train_data = np.load('./train.npy', allow_pickle=True)\n",
    "train_x_set = train_data[0]['train_x']\n",
    "train_y_set = train_data[0]['train_y']\n",
    "\n",
    "eval_data = np.load('./eval.npy', allow_pickle=True)\n",
    "eval_x_set = eval_data[0]['eval_x'][0:100]\n",
    "eval_y_set = eval_data[0]['eval_y'][0:100]\n",
    "\n",
    "train_x_set = train_x_set.reshape((train_x_set.shape[0], -1))\n",
    "eval_x_set = eval_x_set.reshape((eval_x_set.shape[0], -1))\n",
    "\n",
    "# 打印数据信息\n",
    "print(train_x_set.shape)\n",
    "print(train_y_set.shape)\n",
    "\n",
    "print(eval_x_set.shape)\n",
    "print(eval_y_set.shape)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3e1a5291",
   "metadata": {},
   "source": [
    "搭建量子编码器。采用密集比特编码方式，对于 $4*4$ 的图像数据，需要 8 个量子比特。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "id": "c354cf47",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<div class=\"nb-html-output output_area\"><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"216.8\" height=\"500\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<rect x=\"0\" y=\"0\" width=\"216.8\" height=\"500\" fill=\"#ffffff\" />\n",
       "<text x=\"20.0\" y=\"40.0\" font-size=\"16px\" dominant-baseline=\"middle\" text-anchor=\"start\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#252b3a\" >\n",
       "q0:\n",
       " </text>\n",
       "<text x=\"20.0\" y=\"100.0\" font-size=\"16px\" dominant-baseline=\"middle\" text-anchor=\"start\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#252b3a\" >\n",
       "q1:\n",
       " </text>\n",
       "<text x=\"20.0\" y=\"160.0\" font-size=\"16px\" dominant-baseline=\"middle\" text-anchor=\"start\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#252b3a\" >\n",
       "q2:\n",
       " </text>\n",
       "<text x=\"20.0\" y=\"220.0\" font-size=\"16px\" dominant-baseline=\"middle\" text-anchor=\"start\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#252b3a\" >\n",
       "q3:\n",
       " </text>\n",
       "<text x=\"20.0\" y=\"280.0\" font-size=\"16px\" dominant-baseline=\"middle\" text-anchor=\"start\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#252b3a\" >\n",
       "q4:\n",
       " </text>\n",
       "<text x=\"20.0\" y=\"340.0\" font-size=\"16px\" dominant-baseline=\"middle\" text-anchor=\"start\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#252b3a\" >\n",
       "q5:\n",
       " </text>\n",
       "<text x=\"20.0\" y=\"400.0\" font-size=\"16px\" dominant-baseline=\"middle\" text-anchor=\"start\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#252b3a\" >\n",
       "q6:\n",
       " </text>\n",
       "<text x=\"20.0\" y=\"460.0\" font-size=\"16px\" dominant-baseline=\"middle\" text-anchor=\"start\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#252b3a\" >\n",
       "q7:\n",
       " </text>\n",
       "<line x1=\"48.8\" x2=\"196.8\" y1=\"40.0\" y2=\"40.0\" stroke=\"#adb0b8\" stroke-width=\"1\" />\n",
       "<line x1=\"48.8\" x2=\"196.8\" y1=\"100.0\" y2=\"100.0\" stroke=\"#adb0b8\" stroke-width=\"1\" />\n",
       "<line x1=\"48.8\" x2=\"196.8\" y1=\"160.0\" y2=\"160.0\" stroke=\"#adb0b8\" stroke-width=\"1\" />\n",
       "<line x1=\"48.8\" x2=\"196.8\" y1=\"220.0\" y2=\"220.0\" stroke=\"#adb0b8\" stroke-width=\"1\" />\n",
       "<line x1=\"48.8\" x2=\"196.8\" y1=\"280.0\" y2=\"280.0\" stroke=\"#adb0b8\" stroke-width=\"1\" />\n",
       "<line x1=\"48.8\" x2=\"196.8\" y1=\"340.0\" y2=\"340.0\" stroke=\"#adb0b8\" stroke-width=\"1\" />\n",
       "<line x1=\"48.8\" x2=\"196.8\" y1=\"400.0\" y2=\"400.0\" stroke=\"#adb0b8\" stroke-width=\"1\" />\n",
       "<line x1=\"48.8\" x2=\"196.8\" y1=\"460.0\" y2=\"460.0\" stroke=\"#adb0b8\" stroke-width=\"1\" />\n",
       "\n",
       "<rect x=\"72.8\" y=\"20.0\" width=\"40.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" />\n",
       "<text x=\"92.8\" y=\"36.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "RX\n",
       " </text>\n",
       "<text x=\"92.8\" y=\"52.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "rx0\n",
       " </text>\n",
       "\n",
       "\n",
       "<rect x=\"132.8\" y=\"20.0\" width=\"40.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" />\n",
       "<text x=\"152.8\" y=\"36.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "RY\n",
       " </text>\n",
       "<text x=\"152.8\" y=\"52.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "ry0\n",
       " </text>\n",
       "\n",
       "\n",
       "<rect x=\"72.8\" y=\"80.0\" width=\"40.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" />\n",
       "<text x=\"92.8\" y=\"96.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "RX\n",
       " </text>\n",
       "<text x=\"92.8\" y=\"112.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "rx1\n",
       " </text>\n",
       "\n",
       "\n",
       "<rect x=\"132.8\" y=\"80.0\" width=\"40.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" />\n",
       "<text x=\"152.8\" y=\"96.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "RY\n",
       " </text>\n",
       "<text x=\"152.8\" y=\"112.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "ry1\n",
       " </text>\n",
       "\n",
       "\n",
       "<rect x=\"72.8\" y=\"140.0\" width=\"40.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" />\n",
       "<text x=\"92.8\" y=\"156.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "RX\n",
       " </text>\n",
       "<text x=\"92.8\" y=\"172.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "rx2\n",
       " </text>\n",
       "\n",
       "\n",
       "<rect x=\"132.8\" y=\"140.0\" width=\"40.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" />\n",
       "<text x=\"152.8\" y=\"156.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "RY\n",
       " </text>\n",
       "<text x=\"152.8\" y=\"172.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "ry2\n",
       " </text>\n",
       "\n",
       "\n",
       "<rect x=\"72.8\" y=\"200.0\" width=\"40.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" />\n",
       "<text x=\"92.8\" y=\"216.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "RX\n",
       " </text>\n",
       "<text x=\"92.8\" y=\"232.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "rx3\n",
       " </text>\n",
       "\n",
       "\n",
       "<rect x=\"132.8\" y=\"200.0\" width=\"40.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" />\n",
       "<text x=\"152.8\" y=\"216.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "RY\n",
       " </text>\n",
       "<text x=\"152.8\" y=\"232.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "ry3\n",
       " </text>\n",
       "\n",
       "\n",
       "<rect x=\"72.8\" y=\"260.0\" width=\"40.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" />\n",
       "<text x=\"92.8\" y=\"276.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "RX\n",
       " </text>\n",
       "<text x=\"92.8\" y=\"292.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "rx4\n",
       " </text>\n",
       "\n",
       "\n",
       "<rect x=\"132.8\" y=\"260.0\" width=\"40.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" />\n",
       "<text x=\"152.8\" y=\"276.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "RY\n",
       " </text>\n",
       "<text x=\"152.8\" y=\"292.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "ry4\n",
       " </text>\n",
       "\n",
       "\n",
       "<rect x=\"72.8\" y=\"320.0\" width=\"40.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" />\n",
       "<text x=\"92.8\" y=\"336.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "RX\n",
       " </text>\n",
       "<text x=\"92.8\" y=\"352.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "rx5\n",
       " </text>\n",
       "\n",
       "\n",
       "<rect x=\"132.8\" y=\"320.0\" width=\"40.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" />\n",
       "<text x=\"152.8\" y=\"336.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "RY\n",
       " </text>\n",
       "<text x=\"152.8\" y=\"352.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "ry5\n",
       " </text>\n",
       "\n",
       "\n",
       "<rect x=\"72.8\" y=\"380.0\" width=\"40.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" />\n",
       "<text x=\"92.8\" y=\"396.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "RX\n",
       " </text>\n",
       "<text x=\"92.8\" y=\"412.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "rx6\n",
       " </text>\n",
       "\n",
       "\n",
       "<rect x=\"132.8\" y=\"380.0\" width=\"40.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" />\n",
       "<text x=\"152.8\" y=\"396.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "RY\n",
       " </text>\n",
       "<text x=\"152.8\" y=\"412.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "ry6\n",
       " </text>\n",
       "\n",
       "\n",
       "<rect x=\"72.8\" y=\"440.0\" width=\"40.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" />\n",
       "<text x=\"92.8\" y=\"456.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "RX\n",
       " </text>\n",
       "<text x=\"92.8\" y=\"472.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "rx7\n",
       " </text>\n",
       "\n",
       "\n",
       "<rect x=\"132.8\" y=\"440.0\" width=\"40.0\" height=\"40\" rx=\"4\" ry=\"4\" stroke=\"#ffffff\" stroke-width=\"0\" fill=\"#fac209\" fill-opacity=\"1\" />\n",
       "<text x=\"152.8\" y=\"456.0\" font-size=\"20px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "RY\n",
       " </text>\n",
       "<text x=\"152.8\" y=\"472.0\" font-size=\"14.0px\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"Arial\" font-weight=\"normal\" fill=\"#ffffff\" >\n",
       "ry7\n",
       " </text>\n",
       "\n",
       "</svg></div>"
      ],
      "text/plain": [
       "<mindquantum.io.display.circuit_svg_drawer.SVGCircuit at 0x27db0f21508>"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "encoder = Circuit()\n",
    "for i in range(8):\n",
    "    encoder += RX(f'rx{i}').on(i)\n",
    "    encoder += RY(f'ry{i}').on(i)\n",
    "encoder.as_encoder()\n",
    "encoder.svg()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e4755d8c",
   "metadata": {},
   "source": [
    "定义量子卷积核。量子卷积核可以完成任意双量子比特逻辑操作。注意，为避免重复操作，我们省去了每个卷积核最后的两个 U3 门。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "id": "2a125b71",
   "metadata": {},
   "outputs": [],
   "source": [
    "def conv(bit_up=0, bit_down=1, prefix='0'):\n",
    "    _circ = Circuit()\n",
    "    _circ += U3('theta00','phi00','lam00',bit_up)\n",
    "    _circ += U3('theta01','phi01','lam01',bit_down)\n",
    "    _circ += X.on(bit_down,bit_up)\n",
    "    _circ += RY('theta10').on(bit_up)\n",
    "    _circ += RZ('theta11').on(bit_down)\n",
    "    _circ += X.on(bit_up,bit_down)\n",
    "    _circ += RY('theta20').on(bit_up)\n",
    "    _circ += X.on(bit_down,bit_up)\n",
    "    _circ = add_prefix(_circ, 'prefix')\n",
    "    return _circ"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4963fc33",
   "metadata": {},
   "source": [
    "搭建量子卷积神经网络。最终剩余的两个比特上施加 U3 门，来对最终效果进行微调。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "id": "d2e70927",
   "metadata": {},
   "outputs": [],
   "source": [
    "ansatz = Circuit()\n",
    "ansatz += conv(0,1,'00')\n",
    "ansatz += conv(2,3,'01')\n",
    "ansatz += conv(4,5,'02')\n",
    "ansatz += conv(6,7,'03')\n",
    "\n",
    "ansatz += conv(7,0,'10')\n",
    "ansatz += conv(1,2,'11')\n",
    "ansatz += conv(3,4,'12')\n",
    "ansatz += conv(5,6,'13')\n",
    "\n",
    "ansatz += conv(1,3,'20')\n",
    "ansatz += conv(5,7,'21')\n",
    "\n",
    "ansatz += conv(7,1,'30')\n",
    "ansatz += conv(3,5,'31')\n",
    "\n",
    "ansatz += conv(3,7,'40')\n",
    "\n",
    "ansatz += U3('theta400','phi401','lam402', 3)\n",
    "ansatz += U3('theta410','phi411','lam412', 7)\n",
    "ansatz.as_ansatz()\n",
    "\n",
    "circ = encoder + ansatz"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f0257896",
   "metadata": {},
   "source": [
    "定义损失函数。损失函数为带 Softmax 的交叉熵。这一部分完全由经典 MindSpore 构建。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "id": "d56d1ed1",
   "metadata": {},
   "outputs": [],
   "source": [
    "class MyLoss(LossBase):\n",
    "    def __init__(self, reduction='mean'):\n",
    "        super(MyLoss, self).__init__(reduction)\n",
    "        self.cross_entropy = nn.SoftmaxCrossEntropyWithLogits(sparse=True)\n",
    "\n",
    "    def construct(self, logits, label):\n",
    "        out = self.cross_entropy(logits, label)\n",
    "        return self.get_loss(out)\n",
    "\n",
    "class MyWithLossCell(nn.Cell):\n",
    "   def __init__(self, backbone, loss_fn):\n",
    "       super(MyWithLossCell, self).__init__(auto_prefix=False)\n",
    "       self._backbone = backbone\n",
    "       self._loss_fn = loss_fn\n",
    "\n",
    "   def construct(self, x, label):\n",
    "       out = self._backbone(x)\n",
    "       return self._loss_fn(out, label)\n",
    "\n",
    "   @property\n",
    "   def backbone_network(self):\n",
    "       return self._backbone"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c2404de1",
   "metadata": {},
   "source": [
    "装配模型。将量子神经网络、损失函数和优化器等部分封装起来。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "id": "031e8a5c",
   "metadata": {},
   "outputs": [],
   "source": [
    "sim = Simulator('projectq', circ.n_qubits)\n",
    "ham = [Hamiltonian(QubitOperator('Z3')), Hamiltonian(QubitOperator('Z7'))] # 最终通过比较第 3 和第 7 个量子比特能量期望值来作为分类结果。\n",
    "grad_ops = sim.get_expectation_with_grad(ham, circ) \n",
    "qnet = MQLayer(grad_ops)\n",
    "\n",
    "loss = MyLoss()\n",
    "net_with_criterion = MyWithLossCell(qnet, loss)\n",
    "opti = Adam(qnet.trainable_params(), learning_rate=0.1) # 采用 Adam 优化器，学习率设置为 0.1。\n",
    "net = TrainOneStepCell(net_with_criterion, opti) # net 每执行一次，就会对网络进行一次训练。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2d438bdc",
   "metadata": {},
   "source": [
    "训练并显示效果。注意，由于讲座时间有限，为防止程序运行不完，下面程序仅进行了验证性训练，同学门后续可以对程序进行调参，甚至对结构进行更改，以取得更好的训练效果。经本人验证，对这个拥有 846 个样本点的验证集，最终准确率可以超过 0.993。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "id": "56dfed93",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "当前进度为 0 验证集准确率为：0.41\n",
      "当前进度为 10 验证集准确率为：0.7\n",
      "当前进度为 20 验证集准确率为：0.55\n",
      "当前进度为 30 验证集准确率为：0.55\n",
      "当前进度为 40 验证集准确率为：0.45\n",
      "当前进度为 50 验证集准确率为：0.59\n",
      "当前进度为 60 验证集准确率为：0.46\n",
      "当前进度为 70 验证集准确率为：0.82\n"
     ]
    },
    {
     "data": {
      "image/png": "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8G7MdHl9LGVEzRIxKSKjqP7NuaGRlOXLl9f7XEREhH6o/quvvmrwm/F/yeVyjBkzBkBl6/vqv501hpubmz6paugH2rp164w2jaB7zxp6v65du6ZfsVKXsWPH6v+sa+bXHOHh4foC9dWrV+Prr7+GVquFTCYzqPmgv7+/frXQhg0b6v071Wg0+pU8bm5udY7SGJsu8YmJicGZM2f0yREA/fTafxnjc24o3ahdVlYWtmzZUu9xq1atqvc5Y72O6s0vS0tLGzy2IdVHIhuK+8CBAzh9+nStc8yNbvQIqFnvqEuWhBD4+OOPm3193ftuyHtOdWNSREbRvn17/Z/rW6b6+eef49dff633GnK5HM899xwA4MqVK5g8eXK9v+lqtVokJyfX+Nqzzz4LuVwOIQTuv/9+/fL+utT1nG4J7K+//or4+Phaz587dw6vvvpqvddsKt17FhcXh/3799d6vqioCA8++GCDBa4jRoxA7969AQDLli3DunXr6j02MzOzwWvpRov27t2LZcuWAahsbxAWFnbjF9OAWbNmAajsjP3000/XeczChQv1P+xmzJjR5K7ZzfHAAw/of+P+7rvv8MMPPwAAIiMj0aZNmzrPMcbn3FBTpkyBnZ0dAGDevHl1TqPt3r0bK1asqPca7dq107/2r7/+us5Ef8uWLfjkk08ajKV6gX9d/2Yaq1+/fvrO5V9++SWioqJqHZObm4uZM2cCqPxe8cQTTzT7foaIjY1tcDRLCKEv1v/vXmQjR45Ev379AADvv//+DfcRPHHiRJ2Jr+59v3jxYquvzTQ5E/dFolZKq9WKrl276huT3XfffWLLli3iyJEjYtOmTeKee+4RAGrsf1VXEz6NRqPvBoyqztRLliwR+/btE0ePHhVbt24Vr732mmjfvn2d57/55pv6c11dXcXLL78sdu3aJWJiYsRff/0lPvroIzFo0CAxdOjQWudu375df25gYKD46quvRHR0tNi9e7d47bXXhIuLi2jXrp3w8vJqVPPG+vZ30jl06FCNWN9++22xe/du8e+//4rPPvtMtG/fvtZ7Vtc1T58+re96DUDcddddYsOGDeLIkSPi33//Fd99952YMmWKcHBwaDCmoqIi4eLior8OAPHtt982+Boao6KiQkRGRtZoavnTTz+J6Oho8dtvv4m77rpL/1zbtm3rbdrZ0OemuYYOHap/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\n",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "batch_size = 16 # 批大小\n",
    "eval_acc_list = [] # 记录训练过程中，验证集预测准确率\n",
    "\n",
    "for i in range(71):\n",
    "    index = np.random.randint(0, len(train_x_set), size=batch_size) # 每次从训练集中随机抽选 batch_size 的样本。\n",
    "    x = train_x_set[index]\n",
    "    y = train_y_set[index]\n",
    "    net(Tensor(x), Tensor(y, ms.int32)) # 训练一次\n",
    "    \n",
    "    if i % 10 == 0:\n",
    "        res_list = []\n",
    "        for eval_x, eval_y in zip(eval_x_set, eval_y_set):\n",
    "            sim.reset()\n",
    "            params = np.append(eval_x, qnet.weight.asnumpy())\n",
    "            sim.apply_circuit(circ, params)\n",
    "            expectation = [sim.get_expectation(ham[0]).real, sim.get_expectation(ham[1]).real]\n",
    "            out = 0 if expectation[0] >= expectation[1] else 1\n",
    "            res = 1 if eval_y == out else 0\n",
    "            res_list.append(res)\n",
    "        acc = np.mean(res_list)\n",
    "        eval_acc_list.append(acc)\n",
    "        print(f'当前进度为 {i}', f'验证集准确率为：{acc}')\n",
    "    \n",
    "plt.figure()\n",
    "plt.plot(eval_acc_list) \n",
    "plt.title('accuracy of validation set', fontsize=20)\n",
    "plt.xlabel('Steps', fontsize=20)\n",
    "plt.ylabel('Accuracy', fontsize=20)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d0e2e82e",
   "metadata": {},
   "source": [
    "## 参考文献\n",
    "\n",
    "[1] Tak Hur, Leeseok Kim and Daniel K. Park. [Quantum convolutional neural network for classical data classification.](https://arxiv.org/pdf/2108.00661.pdf)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.13"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
